/*jslint sub: true */
/*global */

var Class = (function () {
    'use strict';

    var initialization  = false,
        Class = function () {};

    function $references(prototype, property, method, parent) {
        prototype[property] = function () {
            var self = this,
                args = arguments,
                temp = this['$super'],
                result;
            this['$super'] = function () {
                var result;
                if (typeof parent === 'function') {
                    result = parent.apply(self, args);
                }
                return result;
            };
            result = method.apply(self, args);
            this['$super'] = temp;
            return result;
        };
    }

    function $clone() {
    }

    function $create() {
        initialization = true;
        var object = new this();
        initialization = false;
        if (typeof object['$init'] === 'function') {
            object['$init'].apply(object, arguments);
        }
        return object;
    }

    function $extend(properties) {
        var name,
            property,
            prototype;

        initialization = true;
        prototype = new this();
        initialization = false;

        function Class() {
            if (!initialization && typeof this['$init'] === 'function') {
                this['$parent'] = {};
                this['$init'].apply(this, arguments);
            }
        }

        if (properties) {
            for (property in properties) {
                if (properties.hasOwnProperty(property)) {
                    if (property === '$static') {
                        if (properties['$static']) {
                            for (name in properties['$static']) {
                                if (properties['$static'].hasOwnProperty(name)) {
                                    prototype['$static'][name] = properties[name];
                                }
                            }
                        }
                    } else if (typeof properties[property] === 'function') {
                        $references(prototype, property, properties[property],
                            prototype['$class'] && prototype['$class']['$props'] ? prototype['$class']['$props'][property] : null);
                    } else {
                        prototype[property] = properties[property];
                    }
                }
            }
        }

        if (prototype['$static']) {
            for (property in prototype['$static']) {
                if (prototype['$static'].hasOwnProperty(property)) {
                    Class[property] = prototype['$static'][property];
                }
            }
        }

        Class.prototype                = prototype;
        Class.prototype['constructor'] = Class;
        Class.prototype['$class']      = Class;
        Class.prototype['$clone']      = $clone;
        Class['$props']       = properties;
        Class['$extend']      = $extend;
        Class['$create']      = $create;
        Class['$parent']      = this;
        return Class;
    }

    Class.prototype                = {};
    Class.prototype['constructor'] = Class;
    Class.prototype['$class']      = Class;
    Class.prototype['$clone']      = $clone;
    Class['$props']      = {};
    Class['$extend']     = $extend;
    Class['$create']     = $create;
    Class['$parent']     = null;
    return Class;

}());
